/*
 * Copyright (c) 2024 Shenzhen Kaihong Digital Industry Development Co., Ltd.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef FLOW_MONITOR_MANAGER_H
#define FLOW_MONITOR_MANAGER_H

#include <memory>
#include <mutex>
#include <list>
#include "sle_timer.h"
#include "sle_utils_base_observer_list.h"
#include "sle_error_code.h"

namespace OHOS {
namespace NearLink {
namespace SleStandard {
const int FLOW_MONITOR_PERIOD = 10000;

class ISleFlowMonitorManagerCallback {
public:
    virtual ~ISleFlowMonitorManagerCallback() = default;
    virtual void OnFlowMonitorEvent(float flow) = 0;
};

class SleFlowMonitorManager {
public:
    static SleFlowMonitorManager *GetInstance();
    SleErrorCode RegisterMonitorCallback(ISleFlowMonitorManagerCallback &callback);
    SleErrorCode UnregisterMonitorCallback(ISleFlowMonitorManagerCallback &callback);
    SleErrorCode StartFlowMonitor();
    SleErrorCode StopFlowMonitor();
    bool IsEnableMonitor();
    void WriteDataVolume(float flow);

private:
    class SleFlowMonitorManagerImpl {
    public:
        SleBaseObserverList<ISleFlowMonitorManagerCallback> callbacks_;
        float totalFlow_ = 0;
        std::mutex flowLock_;
        std::unique_ptr<Timer> timer_ = nullptr;

        void AccumulateFlow(float flow);
        void CalculateFlow();
        SleErrorCode EnableMonitor();
        SleErrorCode DisableMonitor();
        SleFlowMonitorManagerImpl();
        ~SleFlowMonitorManagerImpl();
    };

    std::unique_ptr<SleFlowMonitorManagerImpl> pimpl_;
    static SleFlowMonitorManager instance_;
    bool MonitorEnable_ = false;
    std::mutex lock_;
    SleFlowMonitorManager();
    ~SleFlowMonitorManager();
};
} // SleStandard
} // NearLink
} // OHOS

#endif // FLOW_MONITOR_MANAGER_H